package com.aneliya.view.component.input;

import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.EventObject;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import javax.swing.event.EventListenerList;

import com.aneliya.validator.ValidatorListener;
import com.aneliya.validator.component.TextComponentValidator;
import com.aneliya.validator.data.EmptyStringValidator;


public class TextInput extends JPanel {
	private static final long serialVersionUID = 1L;
	
	private static final String SEND_BUTTON_LABEL = "Send";
	
	protected JTextArea inputArea;
	protected JScrollPane scrollPane;
	protected JButton sendButton;
	protected TextComponentValidator validator;
	protected EventListenerList listeners;

	public TextInput() throws Exception {
		listeners = new EventListenerList();
		
		initializeLayout();
		initializeInputArea();
		initializeScrollPane();
		initializeSendButton();
		initializeValidators();
	}
	
	protected void initializeLayout() {
		setLayout(new GridBagLayout());
		setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
	}
	
	protected void initializeInputArea() {
		inputArea = new JTextArea();
		inputArea.setLineWrap(true);
		inputArea.setWrapStyleWord(true);
		
		KeyListener keyListener = new KeyListener() {
			public void keyPressed(KeyEvent e) {
				if (e.getKeyCode()== KeyEvent.VK_ENTER && 
					KeyEvent.getKeyModifiersText(e.getModifiers()).equalsIgnoreCase("Shift")) {
					SwingUtilities.invokeLater(new Runnable() {
						public void run() {
							if (validator.isValid()) {
								dispatchSendButtonClicked();
								resetInputArea();
							}
						}
					});
				}
			}
			
			public void keyReleased(KeyEvent e) {}
			public void keyTyped(KeyEvent e) {}	
		};
		inputArea.addKeyListener(keyListener);
	}
	
	protected void initializeScrollPane() {		
		scrollPane = new JScrollPane(inputArea);
		scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
		scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		scrollPane.setPreferredSize(new Dimension(250, 100));
		
		GridBagConstraints scrollPaneConstraints = new GridBagConstraints();
		scrollPaneConstraints.fill = GridBagConstraints.BOTH;
		scrollPaneConstraints.weightx = 0.5;
		add(scrollPane, scrollPaneConstraints);
	}
	
	protected void initializeSendButton() {		
		sendButton = new JButton(SEND_BUTTON_LABEL);
		sendButton.setEnabled(false);
				
		GridBagConstraints sendButtonConstraints = new GridBagConstraints();
		sendButtonConstraints.fill = GridBagConstraints.NONE;
		sendButtonConstraints.weighty = 0.5;
		sendButtonConstraints.gridx = 1;
		sendButtonConstraints.anchor = GridBagConstraints.PAGE_END;
		sendButtonConstraints.insets = new Insets(0, 10, 10, 10);
		add(sendButton, sendButtonConstraints);	
		
		MouseListener mouseListener = new MouseListener() {
			public void mouseClicked(MouseEvent e) {
				dispatchSendButtonClicked();
				resetInputArea();
			}

			public void mouseEntered(MouseEvent e) {}
			public void mouseExited(MouseEvent e) {}
			public void mousePressed(MouseEvent e) {}
			public void mouseReleased(MouseEvent e) {}
		};
		sendButton.addMouseListener(mouseListener);
	}

	protected void initializeValidators() throws Exception {
		validator = new TextComponentValidator(inputArea, new EmptyStringValidator());
		
		ValidatorListener listener = new ValidatorListener() {
			public void validatorChanged(EventObject e) {
				validatorChangedHandler(e);
			}
		};
		validator.addValidatorListener(listener);
		
	}
	
	protected void validatorChangedHandler(EventObject e) {
		if (validator.isValid()) {
			sendButton.setEnabled(true);
		} else {
			sendButton.setEnabled(false);
		}
	}
	
	public void addTextInputListener(TextInputListener listener) {
		listeners.add(TextInputListener.class, listener);		
	}
	
	public void removeTextInputListener(TextInputListener listener) {
		listeners.remove(TextInputListener.class, listener);		
	}
	
	protected void dispatchSendButtonClicked() {
		TextInputListener[] list = listeners.getListeners(TextInputListener.class);
		for(TextInputListener listener : list) {
			TextInputEvent event = new TextInputEvent(this, inputArea.getText());
			listener.sendButtonClicked(event);
		}	
	}
	
	protected void resetInputArea() {
		inputArea.setText(null);
	}
	
}
